from dao.contract_info_dao import ContractInfoDao
import pandas as pd
from services.commons import Exchange, ContractDateInfo, run_with_timeout
import akshare as ak
from datetime import datetime, timedelta
from config.settings import settings


class ContractInfoService:
    def __init__(self):
        self.contract_info_dao = ContractInfoDao()

    def get_all_contracts_from_db(self) -> pd.DataFrame:
        """获取所有合约信息"""
        return self.contract_info_dao.get_all_contract_info()

    def get_contract_multiplier_from_db(self, symbol: str, exchange: str) -> float | None:
        """获取合约乘数"""
        return self.contract_info_dao.get_contract_info(symbol, exchange)
    
    def get_contract_list_date_and_last_date(self, exchange: Exchange, symbols: list[str]=None) -> pd.DataFrame:
        if exchange == Exchange.CFFEX:
            return self._get_cffex_contract_list_date_and_last_date(symbols)
        else:
            raise ValueError(f"不支持的交易所: {exchange}")
    
    def _get_cffex_contract_list_date_and_last_date(self, symbols: list[str]=None) -> pd.DataFrame:
        try:
            df = pd.DataFrame()
            for i in range(10):
                date = (datetime.now() - timedelta(days=i)).strftime("%Y%m%d")
                try:
                    temp_df = run_with_timeout(ak.futures_contract_info_cffex,  
                                              settings.request_timeout_seconds,  
                                              date=date)
                    if not temp_df.empty:
                        df = temp_df
                        break
                except Exception:
                    continue

            if df.empty:
                print("获取CFFEX合约信息失败: 连续10天没有数据")
                return pd.DataFrame(columns=['symbol', 'month', 'listing_date', 'last_trading_date'])

            # 根据需要筛选合约代码
            if symbols is not None:
                df = df[df['合约代码'].isin(symbols)]
            
            # 重命名列为英文
            df = df.rename(columns={
                '合约代码': 'symbol',
                '合约月份': 'month',
                '上市日': 'listing_date',
                '最后交易日': 'last_trading_date'
            })
            
            # 只返回需要的列
            return df[['symbol', 'month', 'listing_date', 'last_trading_date']]
            
        except Exception as e:
            print(f"获取CFFEX合约信息失败: {e}")
            return pd.DataFrame(columns=['symbol', 'month', 'listing_date', 'last_trading_date'])
